<?php
declare(strict_types=1);
/**
 * Created by PhpStorm
 * User: Administrator
 * Date: 2023/4/10
 * Time: 14:53:11
 */

namespace Service\StoreService;

use App\Model\BbcModel\OrderExtends;
use App\Model\BbcModel\OrderGoods;
use Service\Code\Normal;
use App\Model\BbcModel\BManager;
use App\Model\BbcModel\CashRegister;
use App\Model\BbcModel\Cashcheck;
use App\Model\BbcModel\Mnuser;
use App\Model\BbcModel\OrderReturnExtends;
use Service\AreaService\AreaService;
use App\Model\BbcModel\StoreConfig;
use Service\BaseService;
use Service\PayService\CashPayService;
use Hyperf\DbConnection\Db;

class StoreService extends BaseService
{
    public function cashcheck( array $param)
    {
        $mn_sid          = $param['mn_sid'];
        $cid             = $param['cid'];
        $casher          = $param['manager_id'];
        $cashregister_id = $param['casher_id'];
        $cashcheckdata   = $this->cashcheckdata($param);
        $bmanager        = BManager::instance()->info(['id' => $casher]);
        $cashregister    = Cashregister::instance()->info(['id' => $cashregister_id]);
        $adddata         = $cashcheckdata['data'];
        unset($adddata['goods']);
        unset($adddata['total_sale_goods_num']);
        unset($adddata['total_return_goods_num']);
        unset($adddata['total_goods_num']);
        unset($adddata['giveup_money']);
        $adddata['pay']               = json_encode($adddata['pay']);
        $adddata['total_pay']         = json_encode($adddata['total_pay']);
        $adddata['total_return_pay']  = json_encode($adddata['total_return_pay']);
        $adddata['mn_sid']            = $mn_sid;
        $adddata['cid']               = $cid;
        $adddata['cd']                = time();
        $adddata['cashregister_id']   = $cashregister_id;
        $adddata['cashregister_name'] = $cashregister['name'];
        $adddata['casher_id']         = $casher;
        $adddata['casher_name']       = $bmanager['name'];
        $cashcheckres                 = Cashcheck::instance()->add($adddata);
        if($cashcheckres){
            return Normal::returnCode(Normal::SUC, '成功');
        }else{
            return Normal::returnCode(Normal::FAIL, '失败');
        }
    }

    public function cashcheckdata( array $param)
    {
        $mn_sid = $param['mn_sid'];
        $cid    = $param['cid'];
        $casher = $param['manager_id'];
        $time   = time();
        $cashcheckwhere = [
            ['df', '=', 0],
            ['mn_sid', '=', $mn_sid],
            ['cid', '=', $cid],
            ['casher_id','=',$casher],
            '_order_'=>['id'=>'desc']
        ];
        $where = [
            ['e.mn_sid', '=', $mn_sid],
            ['e.casher', '=', $casher],
        ];
        $first_time = 0;
        $cascheck = Cashcheck::instance()->info($cashcheckwhere);
        if($cascheck){
            $where[] = ['e.cd','>',$cascheck['last_time']];
            $first_time = $cascheck['last_time'];
        }else{
            $where[] = ['e.cd','<=',$time];
        }
        $order_extends_table = OrderExtends::instance()->getTable();
        $order = OrderExtends::instance()->from("{$order_extends_table} as e")
            ->join('ly_order as o','e.order_id','=','o.id')
            ->where($where)
            ->orderBy('e.id', 'asc')
            ->get()->toArray();
        $pay = [
            ['pay_type'=>1,'pay_money'=>0],
            ['pay_type'=>2,'pay_money'=>0],
            ['pay_type'=>3,'pay_money'=>0],
            ['pay_type'=>4,'pay_money'=>0],
            ['pay_type'=>5,'pay_money'=>0],
            ['pay_type'=>7,'pay_money'=>0],
            ['pay_type'=>8,'pay_money'=>0]
        ];
        $data = [
            'first_time'             => $first_time,//上次时间
            'last_time'              => $time,//本次时间
            'money'                  => 0,//总价
            'pay'                    => $pay,//支付
            'num'                    => 0,//总笔数
            'total_money'            => 0,//收款总价
            'total_pay'              => $pay,//收款支付
            'total_num'              => 0,//收款总笔数
            'total_return_money'     => 0,//退款总价
            'total_return_pay'       => $pay,//退款支付
            'total_return_num'       => 0,//退款总笔数
            'total_goods_num'        => 0,//总商品数(含赠品)
            'total_sale_goods_num'   => 0,//总销售商品数(含赠品)
            'total_return_goods_num' => 0,//总退商品数(含赠品)
            'giveup_money'           => 0,//抹零
            'goods'                  => []
        ];
        $data['giveup_money'] = OrderExtends::instance()
            ->from("{$order_extends_table} as e")
            ->join('ly_order as o','e.order_id','=','o.id')
            ->where($where)
            ->where('status','<>',0)
            ->sum('e.giveup_money');
        $order_goods_table = OrderGoods::instance()->getTable();
        $total_sale_goods_num = OrderGoods::instance()
            ->from("{$order_goods_table} as og")
            ->join('ly_order as o','og.order_id','=','o.id')
            ->join('ly_order_extends as e','e.order_id','=','o.id')
            ->join('ly_goods as g','og.goods_id','=','g.id')
            ->where($where)
            ->where([['o.status','>=',40],['o.type','=',3]])
            ->sum('og.num');
        $total_return_goods_num = OrderGoods::instance()
            ->from("{$order_goods_table} as og")
            ->join('ly_order as o','og.order_id','=','o.id')
            ->join('ly_order_extends as e','e.order_id','=','o.id')
            ->join('ly_goods as g','og.goods_id','=','g.id')
            ->where($where)
            ->where([['o.status','=',0],['o.type','=',3]])
            ->sum('og.num');
        $data['total_sale_goods_num'] = $total_sale_goods_num;
//        $data['total_return_goods_num'] = $total_return_goods_num;
        $data['total_goods_num'] = (int)bcadd((string)$total_sale_goods_num, (string)$total_return_goods_num);
        $mnuser= Mnuser::instance()->info(['id'=>$mn_sid]);
        if($mnuser['printgoodsdetail']==1){
            $goods = OrderGoods::instance()
                ->from("{$order_goods_table} as og")
                ->join('ly_order as o','og.order_id','=','o.id')
                ->join('ly_order_extends as e','e.order_id','=','o.id')
                ->join('ly_goods as g','og.goods_id','=','g.id')
                ->where($where)
                ->select('og.goods_id',Db::raw('sum(og.num) as num'),'g.name','g.barcode','g.skucode')
                ->groupBy('og.goods_id')
                ->orderBy('e.id','asc')
                ->get()->toArray();
            $data['goods'] = $goods ?? [];
        }
        $data['total_money'] = $this->bcaddArray(array_column($order, 'price_order'));
        $data['total_num']   = count($order);
        $total_cash          = $this->bcaddArray(array_column($order, 'cash'));
        $total_scan_pay      = $this->bcaddArray(array_column($order, 'scan_pay'));
        $total_scan_rece     = $this->bcaddArray(array_column($order, 'scan_rece'));
        $total_pos           = $this->bcaddArray(array_column($order, 'pos'));
        $total_storecard     = $this->bcaddArray(array_column($order, 'storecard'));
        $total_coupon        = $this->bcaddArray(array_column($order, 'coupon'));
        $total_points        = $this->bcaddArray(array_column($order, 'points'));
        $data['total_pay']= [
            ['pay_type'=>1,'pay_money'=>$total_cash],
            ['pay_type'=>2,'pay_money'=>$total_scan_pay],
            ['pay_type'=>3,'pay_money'=>$total_scan_rece],
            ['pay_type'=>4,'pay_money'=>$total_pos],
            ['pay_type'=>5,'pay_money'=>$total_storecard],
            ['pay_type'=>7,'pay_money'=>$total_coupon],
            ['pay_type'=>8,'pay_money'=>$total_points]
        ];
        $order_return_extends_table = OrderReturnExtends::instance()->getTable();
        $orderreturn = OrderReturnExtends::instance()
            ->from("{$order_return_extends_table} as e")
            ->join('ly_order_return as o','e.order_return_id','=','o.id')
            ->where($where)
            ->select('o.cd','o.amount','e.giveup_money','e.cash','e.scan_pay','e.scan_rece','e.pos','e.storecard','e.cashregister_id','e.casher','e.coupon','e.points','e.order_id')
            ->orderBy('e.id', 'asc')
            ->get()->toArray();
        $data['total_return_goods_num'] = 0;
        foreach ($orderreturn as $v){
            $data['total_return_goods_num'] += OrderGoods::instance()
                ->where(['order_id' => $v['order_id']])
                ->sum('num');
        }
        $data['total_return_money'] = empty($orderreturn) ? 0 : $this->bcaddArray(array_column($orderreturn, 'amount'));
        $data['total_return_num'] = empty($orderreturn) ? 0 : count($orderreturn);
        $total_return_cash = empty($orderreturn) ? 0 : $this->bcaddArray(array_column($orderreturn, 'cash'));
        $total_return_scan_pay = empty($orderreturn) ? 0 : $this->bcaddArray(array_column($orderreturn, 'scan_pay'));
        $total_return_scan_rece = empty($orderreturn) ? 0 : $this->bcaddArray(array_column($orderreturn, 'scan_rece'));
        $total_return_pos = empty($orderreturn) ? 0 : $this->bcaddArray(array_column($orderreturn, 'pos'));
        $total_return_storecard = empty($orderreturn) ? 0 : $this->bcaddArray(array_column($orderreturn, 'storecard'));
        $total_return_coupon = empty($orderreturn) ? 0 : $this->bcaddArray(array_column($orderreturn, 'coupon'));
        $total_return_points = empty($orderreturn) ? 0 : $this->bcaddArray(array_column($orderreturn, 'points'));
        $data['total_return_pay']= [
            ['pay_type'=>1,'pay_money'=>$total_return_cash],
            ['pay_type'=>2,'pay_money'=>$total_return_scan_pay],
            ['pay_type'=>3,'pay_money'=>$total_return_scan_rece],
            ['pay_type'=>4,'pay_money'=>$total_return_pos],
            ['pay_type'=>5,'pay_money'=>$total_return_storecard],
            ['pay_type'=>7,'pay_money'=>$total_return_coupon],
            ['pay_type'=>8,'pay_money'=>$total_return_points]
        ];
        $data['money'] = bcsub((string)$data['total_money'], (string)$data['total_return_money'], 2);
        $data['num'] = bcadd((string)$data['total_num'], (string)$data['total_return_num']);
        $data['pay'] = [
            ['pay_type'=>1,'pay_money'=>bcsub((string)$total_cash, (string)$total_return_cash,2)],
            ['pay_type'=>2,'pay_money'=>bcsub((string)$total_scan_pay, (string)$total_return_scan_pay,2)],
            ['pay_type'=>3,'pay_money'=>bcsub((string)$total_scan_rece, (string)$total_return_scan_rece,2)],
            ['pay_type'=>4,'pay_money'=>bcsub((string)$total_pos, (string)$total_return_pos,2)],
            ['pay_type'=>5,'pay_money'=>bcsub((string)$total_storecard, (string)$total_return_storecard,2)],
            ['pay_type'=>7,'pay_money'=>bcsub((string)$total_coupon, (string)$total_return_coupon,2)],
            ['pay_type'=>8,'pay_money'=>bcsub((string)$total_points, (string)$total_return_points,2)],
        ];
        return Normal::returnCode(Normal::SUC, '成功',$data);
    }

    public function bcaddArray($pram=[])
    {
        $total = 0;
        foreach ($pram as $key => $value) {
            $total= bcadd((string)$total, (string)$value,2);
        }
        return $total;
    }
    
    /**
     * 登录前根据mac获取该渠道下的所有店铺
     * @param array $param
     * @return type
     */
    public function getStoreByMac(array $param)
    {
        if(empty($param['mac'])){
            return Normal::returnCode(Normal::FAIL, 'mac地址必传');
        }
        $cashregister=CashRegister::instance()->info(['df'=>0,'mac'=>$param['mac']]);
        if(empty($cashregister)){
            return Normal::returnCode(Normal::FAIL, '收银台不存在,请先配置收银台');
        }
        $storeList= Mnuser::instance()->lists([
            ['pid','=',$cashregister['cid']],
            ['type','in',[2,3]],
            ['check_status','=',1],
            ['status','=',1],
            '_fields_'=>['store_name','province','city','area','id as mn_sid','store_img']
        ]);
        if(empty($storeList)){
            return Normal::returnCode(Normal::FAIL, '该渠道下未找到前置仓店铺');
        }
        $provinceArea= array_column($storeList, 'province');
        $cityArea= array_column($storeList, 'city');
        $areaArea= array_column($storeList, 'area');
        if(empty($provinceArea)|| empty($cityArea)||empty($areaArea)){
            return Normal::returnCode(Normal::FAIL, '店铺未配置门店自提地址');
        }
        $areaIds= array_merge($provinceArea,$cityArea,$areaArea);
        $aleaList= AreaService::instance()->queryAreaListById($areaIds);
        $mn_sids= array_column($storeList, 'mn_sid');
        
        $store_config= StoreConfig::instance()->lists([
            ['mn_sid','in',$mn_sids],
            ['code','=','cash_login_config']
        ]);
        if(empty($store_config)){
            $store_configMap=[];
        }
        $store_configList= array_column($store_config, 'value','mn_sid');
        foreach ($store_configList as $key => $value) {
            $store_configMap[$key]=$value?@json_decode($value,true):'';
        }
        foreach ($storeList as &$item) {
            $item['cash_login_img']=$store_configMap[$item['mn_sid']]['cash_login_img']??'';
            $item['province_name']=$aleaList[$item['province']]['name']??'';
            $item['city_name']=$aleaList[$item['city']]['name']??'';
            $item['area_name']=$aleaList[$item['area']]['name']??'';
            $item['store_img']=$item['store_img']??'';
        }
        return Normal::returnCode(Normal::SUC, '获取成功', $storeList);
    }

    public function cashSaleDetail(array $param){
        $page   = (int)$param['page'] ?? 1;
        $limit  = (int)$param['limit'] ?? 10;
        $mn_sid = $param['mn_sid'];
        $cid    = $param['cid'];
        $casher = $param['manager_id'];
        $time   = time();
        $cashcheckwhere = [
            ['df', '=', 0],
            ['mn_sid', '=', $mn_sid],
            ['cid', '=', $cid],
            ['casher_id','=',$casher],
            '_order_'=>['id'=>'desc']
        ];
        $where = [
            ['e.mn_sid', '=', $mn_sid],
            ['e.casher', '=', $casher],
        ];
        $cascheck = Cashcheck::instance()->info($cashcheckwhere);
        if($cascheck){
            $where[] = ['e.cd','>',$cascheck['last_time']];
        }else{
            $where[] = ['e.cd','<=',$time];
        }
        $select = [
            'e.id',
            'g.name',
            'g.barcode',
            'g.skucode',
            'og.num',
            'og.spec_num',
            'og.price',
            'og.price_actual',
            'og.price_pay',
            'o.sn',
            'o.cd',
            'e.pay_way',
            'o.pay_time',
        ];
        $order_goods_table = OrderGoods::instance()->getTable();
        $goods_list = OrderGoods::instance()
            ->from("{$order_goods_table} as og")
            ->join('ly_order as o','og.order_id','=','o.id')
            ->join('ly_order_extends as e','e.order_id','=','o.id')
            ->join('ly_goods as g','og.goods_id','=','g.id')
            ->where($where)
            ->where([['o.status','>=',40],['o.type','=',3]])
            ->paginate($limit, $select, 'page', $page);

        $total = $goods_list->total();
        $goods_list = $goods_list->items();
        foreach ($goods_list as &$v){
            $v['pay_time'] = date('Y-m-d H:i:s',$v['pay_time']);
            $v['pay_way_text'] = CashPayService::instance()->pay_way[$v['pay_way']] ?? '';
        }
        return Normal::returnCode(Normal::SUC, '获取成功', ['goods_list'=>$goods_list,'total'=>$total]);
    }
}
